package com.sfexpress.tools;

import java.io.File;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.Writer;

import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.lang.StringUtils;

import com.sfexpress.tools.entity.CheckResult;
import com.sfexpress.tools.entity.MysqlConnInfo;
import com.sfexpress.tools.entity.MysqlConnInfoBuilder;
import com.sfexpress.tools.report.FreeMarkerReporter;
import com.sfexpress.tools.report.Reporter;

/**
 * Main
 * 
 * @author CrazyPig
 *
 */
public class App {
	
	private static final String OPT_PV_HOST = "pvHost";
	private static final String OPT_PV_PORT = "pvPort";
	private static final String OPT_PV_DB = "pvDb";
	private static final String OPT_PV_USER = "pvUser";
	private static final String OPT_PV_PASS = "pvPass";
	
	private static final String OPT_GV_HOST = "gvHost";
	private static final String OPT_GV_PORT = "gvPort";
	private static final String OPT_GV_DB = "gvDb";
	private static final String OPT_GV_USER = "gvUser";
	private static final String OPT_GV_PASS = "gvPass";
	
	private static final String OPT_TABLE = "table";
	
	private static final String OPT_REPORT_FILE = "reportFile";
	
	private static final String OPT_HELP = "h";
	
	private static Options opts;
	private static HelpFormatter hf = new HelpFormatter();
	private static final String CMD_LINE_SYNTAX = "check.sh / check.bat [options]";
	
	private static String pvHost;
	private static String pvPort;
	private static String pvDb;
	private static String pvUser;
	private static String pvPass;
	
	private static String gvHost;
	private static String gvPort;
	private static String gvDb;
	private static String gvUser;
	private static String gvPass;
	
	private static String table;
	private static String reportFile;
	
    public static void main( String[] args ) {
    	
    	createOptions();
    	
    	try {
			if(!parseOptions(args)) {
				hf.printHelp(CMD_LINE_SYNTAX, opts);
				System.exit(-1);
			}
		} catch (ParseException e) {
			e.printStackTrace();
			hf.printHelp(CMD_LINE_SYNTAX, opts);
			System.exit(-1);
		}
    	
    	
    	MysqlConnInfo pvConnInfo = new MysqlConnInfoBuilder().host(pvHost)
    															.port(pvPort)
    															.db(pvDb)
    															.user(pvUser)
    															.password(pvPass)
    															.build();
    	
    	MysqlConnInfo gvConnInfo = new MysqlConnInfoBuilder().host(gvHost)
				.port(gvPort)
				.db(gvDb)
				.user(gvUser)
				.password(gvPass)
				.build();
    	
    	String pvTable = table, gvTable = table; 
    	
        MysqlTableStructChecker checker = new MysqlTableStructChecker();
        CheckResult result = null;
        try {
			result = checker.check(pvConnInfo, pvTable, gvConnInfo, gvTable);
			
			if(StringUtils.isEmpty(reportFile)) {
				reportResult(result, new PrintWriter(System.out));
			} else {
				File file = new File(reportFile);
				FileWriter fw = new FileWriter(file);
				reportResult(result, fw);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
    	
    }
    
    private static void reportResult(CheckResult result, Writer writer) throws Exception {
    	Reporter reporter = new FreeMarkerReporter(result, writer);
    	reporter.report();
    }
    
    private static void createOptions() {
		
		opts = new Options();
		
		Option[] opArr = new Option[] {
				// 生产版本库连接信息
				new Option(OPT_PV_HOST, true, "生产版本库地址"),
				new Option(OPT_PV_PORT, true, "生产版本库端口"),
				new Option(OPT_PV_DB, true, "生产版本库数据库名"),
				new Option(OPT_PV_USER, true, "生产版本库用户名"),
				new Option(OPT_PV_PASS, true, "生产版本库用户密码"),
				
				// 灰度版本库连接信息
				new Option(OPT_GV_HOST, true, "灰度版本库地址"),
				new Option(OPT_GV_PORT, true, "灰度版本库端口"),
				new Option(OPT_GV_DB, true, "灰度版本库数据库名"),
				new Option(OPT_GV_USER, true, "灰度版本库用户名"),
				new Option(OPT_GV_PASS, true, "灰度版本库用户密码"),
				
				// 待校验的表
				new Option(OPT_TABLE, true, "待校验的表名"),
				
				new Option(OPT_REPORT_FILE, true, "结果输出路径(绝对路径)"),
				
				// 帮助信息
				new Option(OPT_HELP, false, "打印帮助信息"),
		};
		
		
		for(int i = 0; i < opArr.length; i++) {
			opts.addOption(opArr[i]);
		}
	
	}
    
    private static boolean parseOptions(String[] args) throws ParseException {
		
		CommandLineParser parser = new DefaultParser();
		CommandLine cmdLine = parser.parse(opts, args);
		
		if(cmdLine.hasOption(OPT_HELP)) {
			hf.printHelp(CMD_LINE_SYNTAX, opts);
			System.exit(0);
		}
		
		if(!cmdLine.hasOption(OPT_PV_HOST)
				|| !cmdLine.hasOption(OPT_PV_PORT)
				|| !cmdLine.hasOption(OPT_PV_DB)
				|| !cmdLine.hasOption(OPT_PV_USER)
				|| !cmdLine.hasOption(OPT_PV_PASS)
				|| !cmdLine.hasOption(OPT_GV_HOST)
				|| !cmdLine.hasOption(OPT_GV_PORT)
				|| !cmdLine.hasOption(OPT_GV_DB)
				|| !cmdLine.hasOption(OPT_GV_USER)
				|| !cmdLine.hasOption(OPT_GV_PASS)
				|| !cmdLine.hasOption(OPT_TABLE)) {
			return false;
		}
		
		pvHost = cmdLine.getOptionValue(OPT_PV_HOST);
		pvPort = cmdLine.getOptionValue(OPT_PV_PORT);
		pvDb = cmdLine.getOptionValue(OPT_PV_DB);
		pvUser = cmdLine.getOptionValue(OPT_PV_USER);
		pvPass = cmdLine.getOptionValue(OPT_PV_PASS);
		
		gvHost = cmdLine.getOptionValue(OPT_GV_HOST);
		gvPort = cmdLine.getOptionValue(OPT_GV_PORT);
		gvDb = cmdLine.getOptionValue(OPT_GV_DB);
		gvUser = cmdLine.getOptionValue(OPT_GV_USER);
		gvPass = cmdLine.getOptionValue(OPT_GV_PASS);
		
		table = cmdLine.getOptionValue(OPT_TABLE);
		
		reportFile = cmdLine.getOptionValue(OPT_REPORT_FILE);
		
		return true;
	}
    
    
}
